<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * Trieda určená na správu udalostí používateľa v databáze.
 * 
 * @author Michal Foltin
 */
class User_model extends CI_Model {

    function __construct() {
        parent::__construct();
    }

    /**
     * Metóda pridá event používateľovi do databázy. Ak event neexistuje, vytvorí ho v databáze, pridá ho používateľovi a vráti true.
     * Ak event existuje a používateľ ho ešte nemá priradený, priradí ho používateľovi a vráti true.
     * Ak event existuje a používateľ ho má priradený, neurobí nič a vráti false.
     * 
     * @param array $data - údaje o importovanom evente; asociatívne pole 
     * array (
     *      'user_id' => integer,
     *      'event' => array (
     *                      'event_type' => integer, 
     *                      'description' => string,
     *                      'event_day' => string,
     *                      'start_time' => integer,
     *                      'end_time' => integer,
     *                      'room_id' => integer 
     *      )
     * )
     * @return boolean - true ak sa pridanie podarilo, inak false 
     */
    function addEvent($data) {
        $this->db->trans_begin();
        $getEvent = $this->db->get_where('event', $data['event'], 1);
        if (wasError()) {
            return false;
        }
        if ($getEvent->num_rows() == 0) {
            $this->db->insert('event', $data['event']);
            if (wasError()) {
                return false;
            }
            $getNewEvent = $this->db->get_where('event', $data['event'], 1);
            $eventId = $getNewEvent->row()->id;
            $teacherId = $data['user_id'];

            $user_event = array(
                'user_id' => $teacherId,
                'event_id' => $eventId
            );

            $this->db->insert('user_events', $user_event);
            if (wasError()) {
                return false;
            }
        } else {
            $getUserEventSql = "SELECT *
            FROM user_events
            WHERE event_id = " . $getEvent->row()->id . " AND user_id = " . $data['user_id'] . ";";
            $getUserEvent = $this->db->query($getUserEventSql);
            if (wasError()) {
                return false;
            }
            if ($getUserEvent->num_rows() == 0) {
                $userEvent = array(
                    'user_id' => $data['user_id'],
                    'event_id' => $getEvent->row()->id
                );
                $this->db->insert('user_events', $userEvent);
                if (wasError()) {
                    return false;
                }
            } else {
                $this->db->trans_rollback();
                return false;
            }
        }
        $this->db->trans_commit();

        if (wasError()) {
            $this->db->trans_rollback();
            return false;
        } else {
            return true;
        }
    }

    /**
     * Metóda umožní upraviť informácie o evente v databáze.
     * 
     * @param array $data - údaje o upravovanom evente; asociatívne pole
     * array (
     *      'event_id' => integer,
     *      'event' => array(event_type, event_description, event_day, start_time, end_time, room_id) - pole upravovaných položiek
     * )
     * @return boolean - true ak sa update podaril, inak false
     */
    function editEvent($data) {
        if (empty($data['event'])) {
            return false;
        }
        $this->db->trans_begin();
        $where = array('id' => $data['event_id']);
        $getEvent = $this->db->get_where('event', $where);
        if ($getEvent->num_rows() == 0) {
            $this->db->trans_rollback();
            return false;
        }

        $this->db->update('event', $data['event'], $where);
        if (wasError()) {
            $this->db->trans_rollback();
            return false;
        } else {
            $this->db->trans_commit();
            return true;
        }
    }

    /**
     * Metóda odstráni event používateľovi z databázy. Ak event po odobratí používateľovi už nepatrí žiadnemu ďalšiemu,
     * metóda odstráni z databázy aj tento event.
     * 
     * @param array $data - údaje o odstraňovanom evente asociatívne pole
     * array (
     *      'user_id' => integer,
     *      'event_id' => integer
     * )
     * @return boolean - true ak sa odstránenie podarilo, inak false
     */
    function deleteEvent($data) {
        $this->db->trans_begin();

        $userEvent = array('user_id' => $data['user_id'], 'event_id' => $data['event_id']);
        $whereEvent = array('event_id' => $data['event_id']);
        $eventId = array('id' => $data['event_id']);

        $getUserEvents = $this->db->get_where('user_events', $userEvent);

        if ($getUserEvents->num_rows() > 0) {
            $this->db->delete('user_events', $userEvent);
            $getRemainingEvents = $this->db->get_where('user_events', $whereEvent);
            if ($getRemainingEvents->num_rows() == 0) {
                $this->db->delete('event', $eventId);
            }
        } else {
            $this->db->trans_rollback();
            return false;
        }

        $this->db->trans_commit();
        if (wasError()) {
            $this->db->trans_rollback();
            return false;
        } else {
            return true;
        }
    }

    /**
     * Metóda vráti zoznam eventov na základe podmienky $condition
     * 
     * @param array $condition - podmienka pre získanie eventov
     * array (
     *      'event_id' => array(integer),
     *      'event_type' => array(integer),
     *      'description' => array(string),
     *      'event_day' => array(string),
     *      'start_time' => array(min_time, max_time),
     *      'end_time' => array(min_time, max_time),
     *      'room_id' => array(integer),
     *      'users' => array(integer) - user ids: ak je nastavené condition['users'], tak obsahuje len tých userov, podľa ktorých sa vyhľadáva,
     *                                              inak obsahuje všetkých userov ktorým event patrí
     * )
     * @return array - všetky eventy vyhovujúce podmienke; asociatívne pole:
     * array(id, event_type, description, event_day, start_time, end_time, room_id, users => array(integer))
     */
    function getEvents($condition) {
        $data = array();

        $getEventsQuery = "SELECT e.*
            FROM event e
            WHERE 1=1 ";

        if (isset($condition['event_id']) && !empty($condition['event_id'])) {
            $getEventsQuery .= " AND e.id IN (";
            $getEventsQuery .= implode($condition['event_id'], ', ');
            $getEventsQuery .= ")";
        }

        if (isset($condition['event_type']) && !empty($condition['event_type'])) {
            $getEventsQuery .= " AND e.event_type IN (";
            $getEventsQuery .= implode($condition['event_type'], ', ');
            $getEventsQuery .= ")";
        }

        if (isset($condition['description']) && !empty($condition['description'])) {
            $getEventsQuery .= " AND e.description IN (";
            $getEventsQuery .= implode($condition['description'], ', ');
            $getEventsQuery .= ")";
        }

        if (isset($condition['event_day']) && !empty($condition['event_day'])) {
            $getEventsQuery .= " AND e.event_day IN (";
            $getEventsQuery .= "'" . implode($condition['event_day'], "', '") . "'";
            $getEventsQuery .= ")";
        }

        if (isset($condition['start_time']) && isset($condition['start_time'][0]) && isset($condition['start_time'][1])) {
            $startTimeCondition = $condition['start_time'];
            $getEventsQuery .= " AND e.start_time between " . $startTimeCondition[0] . " AND " . $startTimeCondition[1];
        }

        if (isset($condition['end_time']) && isset($condition['end_time'][0]) && isset($condition['end_time'][1])) {
            $endTimeCondition = $condition['end_time'];
            $getEventsQuery .= " AND e.end_time between " . $endTimeCondition[0] . " AND " . $endTimeCondition[1];
        }

        if (isset($condition['room_id']) && !empty($condition['room_id'])) {
            $getEventsQuery .= " AND e.room_id IN (";
            $getEventsQuery .= implode($condition['room_id'], ', ');
            $getEventsQuery .= ")";
        }

        if (isset($condition['users']) && !empty($condition['users'])) {
            $getEventsQuery .= " AND EXISTS (SELECT user_id FROM user_events ue WHERE ue.event_id = e.id AND ue.user_id IN (";
            $getEventsQuery .= implode($condition['users'], ', ');
            $getEventsQuery .= "))";
        }

        $getEventsQuery .= "
            ORDER BY e.event_day, e.start_time, e.end_time, e.id;";

        $getEvents = $this->db->query($getEventsQuery);
        if (wasError()) {
            return array();
        }

        foreach ($getEvents->result() as $row) {
            $getUsers = $this->db->get_where('user_events', array('event_id' => $row->id));
            $users = array();
            foreach ($getUsers->result() as $user) {
                if (isset($condition['users']) && !empty($condition['users'])) {
                    if (in_array($user->user_id, $condition['users'])) {
                        array_push($users, $user->user_id);
                    }
                } else {
                    array_push($users, $user->user_id);
                }
            }
            $event = array(
                'id' => $row->id,
                'event_type' => $row->event_type,
                'description' => $row->description,
                'event_day' => $row->event_day,
                'start_time' => $row->start_time,
                'end_time' => $row->end_time,
                'room_id' => $row->room_id,
                'users' => $users
            );
            array_push($data, $event);
        }

        return $data;
    }

    /**
     * Metóda vráti zoznam všetkých miestností z databázy.
     * 
     * @return array - asociatívne štruktúrované pole (klúč => hodnota) na základe hlavičky tabuľky room.
     */
    function getRooms() {
        $query = $this->db->get('room');
        return $query->result_array();
    }

    /**
     * Metóda vráti jednu miestnosť z databázy
     * 
     * @param int $id - id miestnosti
     * @return array - požadovaná miestnosť
     */
    function getRoom($id) {
        $data['id'] = $id;
        $query = $this->db->get_where('room', $data);
        return $query->row_array();
    }

    /**
     * Metóda pridá do databázy typ eventu ktorý v nej ešte nie je a vráti jeho id.
     * 
     * @param string $eventTypeName - názov nového eventu
     * @return int - id pridaného typu eventu
     */
    function addEventType($eventTypeName) {
        $this->db->insert('event_type', array('event_type' => $eventTypeName));
        $getNewEventId = $this->db->query("SELECT id FROM event_type ORDER BY id DESC LIMIT 1");
        return $getNewEventId->row()->id;
    }

    /**
     * Metóda vráti zoznam všetkých typov eventov z databázy
     * 
     * @return array - asociatívne štruktúrované pole (klúč => hodnota) na základe hlavičky tabuľky event_type.
     */
    function getEventTypes() {
        $query = $this->db->get('event_type');
        return $query->result_array();
    }

}

?>